<script lang="ts">
import { Component, Inject, Vue, Watch } from 'vue-facing-decorator';
import { getNovelChapter, saveChapter, setNovelChapterVisibility } from '@/api/novel/novel';
import type { ChapterInfo, ChapterData } from '@/api/novel/novel';
import { ElMessage, ElMessageBox } from 'element-plus';
import dayjs from 'dayjs';
import TextEditor from '@/components/editor/TextEditor.vue';
import type { UserInfo } from '@/api/auth/auth';
import UserLink from '@/pages/profile/component/UserLink.vue';

@Component({
  components: {
    TextEditor,
    UserLink,
  },
})
export default class NovelChapterPage extends Vue {
  @Inject() userInfo!: UserInfo;
  get isMyNovel() {
    if (!this.userInfo?.id) return false;
    if (!this.chapter?.novel?.author?.id) return false;
    return this.userInfo.id === this.chapter.novel.author.id;
  }

  dayjs = dayjs;

  get nid() {
    return +(this.$route.params.nid + '');
  }
  get cid() {
    return +(this.$route.params.cid + '');
  }

  chapter: ChapterInfo | null = null;
  editForm: ChapterData | null = null;
  autoSaveDraft: boolean = false;
  
  async initNovel() {
    const resp = await getNovelChapter(this.nid, this.cid);
    if (resp.error != null) {
      ElMessage({ type: 'error', message: resp.error });
      this.$router.push('/novel/' + this.nid + '/chapter/' + this.cid);
      return;
    }
    this.chapter = resp.data;
    const authorId = this.chapter.novel?.author?.id;
    if (authorId !== this.userInfo.id) {
      ElMessage({ type: 'error', message: '您不能编辑这篇文章' });
      this.$router.push('/novel/' + this.nid + '/chapter/' + this.cid);
      return;
    }
    this.editForm = {
      title: this.chapter.draft?.title ?? this.chapter.title,
      content: this.chapter.draft?.content ?? this.chapter.content,
    };
  }
  
  get publishedData() {
    if (!this.chapter) return null;
    return {
      title: this.chapter.title,
      content: this.chapter.content,
    };
  }
  get savedDraftData() {
    if (!this.chapter) return null;
    if (!this.chapter.draft) return this.publishedData;
    return {
      title: this.chapter.draft.title ?? this.chapter.title,
      content: this.chapter.draft.content ?? this.chapter.content,
    };
  }
  get isModifiedCompareToPublished() {
    if (!this.editForm) return false;
    if (!this.publishedData) return true;
    return this.publishedData.title !== this.editForm.title || this.publishedData.content !== this.editForm.content;
  }
  get isModifiedCompareToSavedDraft() {
    if (!this.editForm) return false;
    if (!this.savedDraftData) return true;
    return this.savedDraftData.title !== this.editForm.title || this.savedDraftData.content !== this.editForm.content;
  }

  @Watch('nid')
  @Watch('cid')
  onParamsChange() {
    this.chapter = null;
    this.initNovel();
  }

  async saveChapter(publish: boolean) {
    if (!this.chapter || !this.editForm) return;
    const resp = await saveChapter(this.nid, this.cid, {
      visibility: publish,
      title: this.editForm.title,
      content: this.editForm.content,
    });
    if (resp.error != null) {
      ElMessage({ type: 'error', message: resp.error });
      return;
    }
    this.chapter = resp.data;
  }
  
  autoSaveTimer: ReturnType<typeof setTimeout> | null = null;
  @Watch('autoSaveDraft', { immediate: true })
  onAutoSaveDraftChange() {
    if (this.autoSaveTimer) {
      clearTimeout(this.autoSaveTimer);
      this.autoSaveTimer = null;
    }
    if (this.autoSaveDraft) {
      const runSave = () => {
        this.saveChapter(false);
        this.autoSaveTimer = setTimeout(runSave, 180e3);
      };
      runSave();
    }
  }

  async setVisibility(visibility: boolean) {
    const title = visibility ? '发布章节' : '隐藏章节';
    const text = visibility ? '确认要发布此章节吗？' : '确认要隐藏此章节吗？';
    if (!await ElMessageBox.confirm(text, title).then(() => true, () => false)) return;
    if (!this.chapter) return;
    const resp = await setNovelChapterVisibility(this.nid, this.cid, visibility);
    if (resp.error != null) {
      ElMessage({ type: 'error', message: resp.error });
      return;
    }
    this.chapter = resp.data;
  }

  mounted() {
    this.initNovel();
  }
}
</script>
<template>
  <div class="novel-chapter-edit-page" v-if="chapter">
    <div class="novel-info">
      <router-link :to="'/novel/' + nid" class="novel-chapter-back">{{ chapter.novel.title }}</router-link>
      &nbsp;<el-icon><el-icon-arrow-right /></el-icon>&nbsp;
      <router-link :to="'/novel/' + nid + '/chapter/' + cid" class="novel-chapter-back">{{ chapter.title }}</router-link>
    </div>
    <div class="novel-chapter" v-if="chapter && editForm">
      <div class="novel-chapter-title">
        <el-input class="novel-chapter-title-input" v-model="editForm.title" placeholder="章节标题">
          <template #prepend>
            <el-icon><el-icon-view v-if="chapter.visibility" /><el-icon-hide v-else /></el-icon>
            &nbsp;{{ chapter.visibility ? '已发布' : '未发布' }}
          </template>
        </el-input>
      </div>
      <div class="novel-chapter-content">
        <text-editor v-model="editForm.content" />
      </div>
      <div class="novel-chapter-edit-actions">
        <div class="novel-chapter-edit-draft">
          <el-button class="novel-chapter-edit-action" icon="el-icon-check" @click="saveChapter(false)" :disabled="!isModifiedCompareToSavedDraft">保存草稿</el-button>
          <el-switch class="novel-chapter-edit-action" v-model="autoSaveDraft" active-text="自动保存草稿" title="开启后每3分钟会自动保存一次草稿" />
        </div>
        <div class="novel-chapter-edit-publish">
          <el-button v-if="chapter.visibility" class="novel-chapter-edit-action" icon="el-icon-hide" @click="setVisibility(false)">隐藏章节</el-button>
          <el-button type="primary" class="novel-chapter-edit-action" icon="el-icon-check" @click="saveChapter(true)">保存并发布</el-button>
        </div>
      </div>
    </div>
  </div>
</template>
<style scoped>
.novel-chapter-edit-page {
  display: flow-root;
  max-width: 1000px;
  margin: 20px auto;
  padding: 0 20px;
  background-color: var(--el-bg-color-overlay);
  color: var(--el-text-color-primary);
  display: flow-root;
}

.tiny-mode .novel-chapter-edit-page {
  padding: 0 10px;
}

.novel-info {
  margin-bottom: 20px;
}

.novel-chapter {
  margin-bottom: 20px;
}

.novel-chapter-title {
  margin-bottom: 10px;
}

.novel-chapter-title-input {
  font-size: 120%;
  height: 60px;
}

.novel-chapter-title h1 {
  margin: 0;
  font-size: 150%;
  font-weight: bold;
}

.novel-chapter-metadata {
  margin-bottom: 20px;
  color: var(--el-text-color-secondary);
  display: flex;
}

.novel-chapter-metadata-time {
  margin-left: auto;
}

.novel-chapter-content {
  margin-top: 20px;
}

.novel-chapter-edit-actions {
  margin-top: 20px;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
}

.novel-chapter-edit-draft,
.novel-chapter-edit-publish {
  flex: 1;
  display: flex;
  gap: 10px;
  flex-wrap: nowrap;
}

.novel-chapter-edit-publish {
  justify-content: end;
}

.novel-chapter-edit-draft .el-button,
.novel-chapter-edit-publish .el-button {
  margin: 0;
}

.novel-chapter-edit-actions .el-switch {
  white-space: nowrap;
}
</style>
